/**
 * Wihidum - Efficient Broker Hierarchy for Publish Subscribe Middleware
 *
 * License      :   Apache License 2.0
 * Home Page    :   http://code.google.com/p/wihidum/
 * Mailing List :   wihidum@googlegroups.com
 */

package lk.mrt.cse.wihidum.subscriber.client;

import org.apache.axiom.om.*;
import org.apache.axis2.*;
import org.apache.axis2.addressing.*;
import org.apache.axis2.client.*;

import javax.xml.namespace.*;
import java.util.*;

/**
 * Client invoking subscriber service
 */
public class Client
{
    private UserInterface userInterface;

    public Client (UserInterface userInterface)
    {
        this.userInterface = userInterface;
    }

    /**
     * Invoking subscribe method in subscriber service
     *
     * @param subscriptionID    ID of subscriber client
     * @param brokerAddress     Address of broker
     * @param publisherAddress  Address of publisher
     * @param listenerAddress   Address of listener
     * @param subscriberAddress Address of subscriber
     * @param topic             Subscribing topic
     */
    public void subscribe (String subscriptionID, String brokerAddress, String publisherAddress, String listenerAddress, String subscriberAddress, String topic)
    {
        try
        {
            ServiceClient serviceClient = new ServiceClient ();
            Options options = new Options ();
            options.setTo (new EndpointReference (subscriberAddress));
            options.setAction ("subscribe");
            serviceClient.setOptions (options);
            
            OMFactory factory = OMAbstractFactory.getOMFactory ();

            OMElement messageElement = factory.createOMElement ("SubscriptionRequest", null);

            OMElement subscriptionHeader = factory.createOMElement ("Header", null);
            OMElement actionElement = factory.createOMElement ("Action", null);
            actionElement.setText ("subscribe");
            subscriptionHeader.addChild (actionElement);
            messageElement.addChild (subscriptionHeader);

            OMElement subscriptionIDElement = factory.createOMElement ("subscriptionID", null);
            subscriptionIDElement.setText (subscriptionID);
            messageElement.addChild (subscriptionIDElement);

            OMElement brokerAddressElement = factory.createOMElement ("brokerAddress", null);
            brokerAddressElement.setText (brokerAddress);
            messageElement.addChild (brokerAddressElement);

            OMElement publisherAddressElement = factory.createOMElement ("publisherAddress", null);
            publisherAddressElement.setText (publisherAddress);
            messageElement.addChild (publisherAddressElement);

            OMElement listenerAddressElement = factory.createOMElement ("listenerAddress", null);
            listenerAddressElement.setText (listenerAddress);
            messageElement.addChild (listenerAddressElement);

            OMElement subscriberAddressElement = factory.createOMElement ("subscriberAddress", null);
            subscriberAddressElement.setText (subscriberAddress);
            messageElement.addChild (subscriberAddressElement);

            OMElement topicElement = factory.createOMElement ("topic", null);
            topicElement.setText (topic);
            messageElement.addChild (topicElement);

            OMElement responseElement = serviceClient.sendReceive (messageElement);

            OMElement referenceParameters = responseElement.getFirstChildWithName (new QName ("ReferenceParameters"));
            OMElement responseTextElement = referenceParameters.getFirstChildWithName (new QName ("Response"));

            userInterface.showInfo (responseTextElement.getText ());
        }
        catch (NullPointerException ex)
        {
            userInterface.showError ("Error in processing subscription response");
        }
        catch (AxisFault ex)
        {
            userInterface.showError ("Error in sending subscription request");
        }
    }
    public void unsusbcribe(String listenerServiceAddress, String clientID,String filterTopic)
    {

    }
    public void getPublications (String subscriptionID, String subscriberAddress, String listenerAddress)
    {
        try
        {
            ServiceClient serviceClient = new ServiceClient ();
            Options options = new Options ();
            options.setTo (new EndpointReference (subscriberAddress));
            options.setAction ("getPublications");
            serviceClient.setOptions (options);

            OMFactory factory = OMAbstractFactory.getOMFactory ();

            OMElement messageElement = factory.createOMElement ("GetPublicationsRequest", null);

            OMElement subscriptionHeader = factory.createOMElement ("Header", null);
            OMElement actionElement = factory.createOMElement ("Action", null);
            actionElement.setText ("getPublications");
            subscriptionHeader.addChild (actionElement);
            messageElement.addChild (subscriptionHeader);

            OMElement subscriptionIDElement = factory.createOMElement ("subscriptionID", null);
            subscriptionIDElement.setText (subscriptionID);
            messageElement.addChild (subscriptionIDElement);

            OMElement listenerAddressElement = factory.createOMElement ("listenerAddress", null);
            listenerAddressElement.setText (listenerAddress);
            messageElement.addChild (listenerAddressElement);

            OMElement responseElement = serviceClient.sendReceive (messageElement);

            OMElement referenceParameters = responseElement.getFirstChildWithName (new QName ("ReferenceParameters"));
            OMElement responseTextElement = referenceParameters.getFirstChildWithName (new QName ("Response"));

            userInterface.clearTable ();

            for (Iterator<OMElement> publicationElement = responseTextElement.getChildrenWithName (new QName ("Publication")); publicationElement.hasNext ();)
            {
                OMElement nextPublication = publicationElement.next ();
                OMElement publisher = nextPublication.getFirstChildWithName (new QName ("publisherAddress"));
                OMElement topic = nextPublication.getFirstChildWithName (new QName ("topic"));
                OMElement publicationText = nextPublication.getFirstChildWithName (new QName ("publicationText"));

                userInterface.newPublicationReceived (publisher.getText (), topic.getText (), publicationText.getText ());
            }

            userInterface.showInfo (responseTextElement.getText ());
        }
        catch (NullPointerException ex)
        {
            userInterface.showError ("Error in processing get publications response");
        }
        catch (AxisFault ex)
        {
            userInterface.showError ("Error in sending get publications request");
        }
    }
}
